package app.controllers;

import java.text.ParseException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.util.DateParseException;
import org.apache.log4j.Logger;

import app.models.Consulta;
import app.models.Especialidade;
import app.models.Funcionario;
import app.models.SubEspecialidade;
import app.models.enums.TipoConsulta;
import app.models.to.RelatorioConsulta;
import app.models.to.RelatorioFaturamento;
import app.services.ConsultaService;
import app.services.EspecialidadeService;
import app.services.FuncionarioService;
import app.services.RelatorioService;
import app.services.SubEspecialidadeService;
import app.session.UserSession;
import app.util.PlanningReportConsulta;
import app.util.PlanningReportFaturamento;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.interceptor.download.Download;
import br.com.caelum.vraptor.jasperreports.Report;
import br.com.caelum.vraptor.jasperreports.download.ReportDownload;
import br.com.caelum.vraptor.jasperreports.formats.ExportFormats;
import br.com.caelum.vraptor.validator.ValidationMessage;

@Resource
public class RelatorioController extends Controller {

	private final Result result;
	private final RelatorioService service;
	private final ConsultaService consultaService;
	private final EspecialidadeService especialidadeService;
	private final SubEspecialidadeService subEspecialidadeService;
	private final FuncionarioService funcionarioService;
	private final Validator validator;
	private final HttpServletResponse response;
	private final ServletContext servletContext;
	private final HttpServletRequest request;
	private final UserSession userSession;
	
	
	public RelatorioController(Result result, RelatorioService service, ConsultaService consultaService,
			EspecialidadeService especialidadeService, SubEspecialidadeService subEspecialidadeService,
			FuncionarioService funcionarioService,
			Validator validator, HttpServletResponse response, ServletContext servletContext, HttpServletRequest request,
			UserSession userSession) {

		this.result = result;
		this.service = service;
		this.consultaService = consultaService;
		this.especialidadeService = especialidadeService;
		this.subEspecialidadeService = subEspecialidadeService;
		this.funcionarioService = funcionarioService;
		this.validator = validator;
		this.response = response;
		this.servletContext = servletContext;
		this.request = request;
		this.userSession = userSession;
	}
	
	private static final Logger LOGGER = Logger.getLogger(RelatorioController.class);

	
	@Get("/relatorios/faturamento")
	public Download faturamento(RelatorioFaturamento relatorioFaturamento) throws ParseException, DateParseException {
		
		List<RelatorioFaturamento> faturamentos = service.findRelatorioFaturamentosByFilters(relatorioFaturamento);
		
		// Ação de acordo com "submit" acionado
		if (null != request.getParameter("submit")) {
			if (request.getParameter("submit").equals("Limpar")) {
				relatorioFaturamento = new RelatorioFaturamento();
			}
			
			if (request.getParameter("submit").equals("Exportar PDF")) {
				return pdfPlanningReportFaturamento(faturamentos);
			}
			
			if (request.getParameter("submit").equals("Exportar Excel")) {
				return xlsPlanningReportFaturamento(faturamentos);
			}
		}
		
		validator.onErrorRedirectTo(this);
		
		this.result.include("relatorioFaturamento", relatorioFaturamento);
		this.result.include("faturamentos", faturamentos);
		
		this.result.forwardTo(this).faturamento();
		
		return null;
		
	}
	
	
	@Get("/relatorios/consulta")
	public Download consulta(Consulta consulta) throws ParseException, DateParseException {
		
		List<RelatorioConsulta> relatorioConsultas = service.findRelatorioConsultasByFilters(consulta);
		
		// Ação de acordo com "submit" acionado
		if (null != request.getParameter("submit")) {
			if (request.getParameter("submit").equals("Limpar")) {
				consulta = new Consulta();
			}
			
			if (request.getParameter("submit").equals("Exportar PDF")) {
				return pdfPlanningReportConsulta(relatorioConsultas);
			}
			
			if (request.getParameter("submit").equals("Exportar Excel")) {
				return xlsPlanningReportConsulta(relatorioConsultas);
			}
		}
		
		this.result.include("tipos", TipoConsulta.values());
		this.result.include("consulta", consulta);
		this.result.include("consultas", consultaService.findConsultasByFilters(consulta, null, null, null));
		
		if (consulta.getTipo() == TipoConsulta.PARTICULAR) {
			List<Especialidade> especialidades = especialidadeService.findAllOrdered();
			
			if (especialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Particular\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
						"href=\"" + handleMe(request) + "/especialidades/new\">Cadastrar uma Especialidade Particular</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("especialidades", especialidades);
			}
		} else if (consulta.getTipo() == TipoConsulta.CONVENIO) {
			List<SubEspecialidade> subEspecialidades = subEspecialidadeService.findAllOrdered();
			
			if (subEspecialidades.isEmpty()) {
				validator.add(new ValidationMessage("Necessário " +
						"<a title=\"Clique aqui para Cadastrar Especialidade Convênio\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
						"href=\"" + handleMe(request) + "/subEspecialidades/new\">Cadastrar uma Especialidade Convênio</a> " +
								"para que possa ser utilizado o filtro de Especialidades", "erro"));
			} else {
				this.result.include("subEspecialidades", subEspecialidades);
			}
		}
		
		List<Funcionario> especialistas = funcionarioService.findAllOrdered();
		
		if (especialistas.isEmpty()) {
			validator.add(new ValidationMessage("Necessário " +
					"<a title=\"Clique aqui para Cadastrar Especialista\" data-toggle=\"modal\" data-dismiss=\"modal\" aria-hidden=\"true\" " +
					"href=\"" + handleMe(request) + "/funcionarios/new\">Cadastrar um Especialista</a> " +
							"para que possa ser utilizado o filtro de Especialistas", "erro"));
		} else {
			if (null != consulta.getIdEspecialidade()) {
				Especialidade especialidade = especialidadeService.find(consulta.getIdEspecialidade().longValue());
				
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(especialidade.getId()));
			} else if (null != consulta.getIdSubEspecialidade()) {
				SubEspecialidade subEspecialidade = subEspecialidadeService.find(consulta.getIdSubEspecialidade().longValue());
				
				this.result.include("especialistas", funcionarioService.findEspecialistasByEspecialidade(Long.valueOf(subEspecialidade.getEspecialidade().getId())));
			} else {
				this.result.include("especialistas", especialistas);
			}
		}
		
		validator.onErrorRedirectTo(this);
		
		this.result.include("consulta", consulta);
		this.result.forwardTo(this).consulta();
		
		return null;
	}
	
	public void consulta() { }
	
	public void faturamento() { }
	
    public Download pdfPlanningReportConsulta(List<RelatorioConsulta> relatorioConsulta) {
        Report report = new PlanningReportConsulta(relatorioConsulta);
        
        ReportDownload download = new ReportDownload(report, ExportFormats.pdf(), false);
        
        this.response.setHeader("Content-disposition", "inline; filename=" + download.getFileName() + ";");
        
        return download;
    }
    
    public Download xlsPlanningReportConsulta(List<RelatorioConsulta> relatorioConsulta) {
        Report report = new PlanningReportConsulta(relatorioConsulta);
        
        ReportDownload download = new ReportDownload(report, ExportFormats.xlsx(), true);
        
        return download;
    }

	
    public Download pdfPlanningReportFaturamento(List<RelatorioFaturamento> faturamentos) {
        Report report = new PlanningReportFaturamento(faturamentos);
        
        ReportDownload download = new ReportDownload(report, ExportFormats.pdf(), false);
        
        this.response.setHeader("Content-disposition", "inline; filename=" + download.getFileName() + ";");
        
        return download;
    }
    
    public Download xlsPlanningReportFaturamento(List<RelatorioFaturamento> faturamentos) {
        Report report = new PlanningReportFaturamento(faturamentos);
        
        ReportDownload download = new ReportDownload(report, ExportFormats.xlsx(), true);
        
        return download;
    }
	
}
